package com.winshare.saleAssistant.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisListCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.*;


@Component
@Slf4j
public class RedisUtils {

	private static final String REDIS_CHARSET = "utf-8";

	/** 缓存1个月 **/
	public static final long LIVE_TIME_MONTH = 30 * 24 * 60 * 60;
	/** 缓存1周 **/
	public static final long LIVE_TIME_WEEK = 7 * 24 * 60 * 60;
	/** 缓存1天 **/
	public static final long LIVE_TIME_DAY = 24 * 60 * 60;
	/** 缓存1小时 **/
	public static final long LIVE_TIME_HOUR = 60 * 60;
	/** 缓存1分钟 **/
	public static final long LIVE_TIME_MIN = 60;
	/** 缓存1秒 **/
	public static final long LIVE_TIME_SEC = 1L;

	public RedisUtils() {
		System.err.println("redisUtils is init....");
	}


	  @Resource
	  protected RedisTemplate<Serializable, Serializable> redisTemplate;

	  public Long del(String... keys)
	  {
		  return this.redisTemplate.execute(new RedisCallback<Long>() {
			@Override
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
		        long result = 0L;
		        for (int i = 0; i < keys.length; i++) {
		          result = connection.del(new byte[][] { keys[i].getBytes() }).longValue();
		        }
		        return Long.valueOf(result);
			}
		});
	  }

	  public Boolean expire( String key,  long liveTime)
	  {
		 return this.redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.expire(key.getBytes(), liveTime);
			}
		});
	  }

	  public Boolean persist( String key)
	  {
	    return (Boolean)this.redisTemplate.execute(new RedisCallback<Boolean>() {
	      @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.persist(key.getBytes());
	      }
	    });
	  }

	  public Long ttl( String key)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.ttl(key.getBytes());
	      }
	    });
	  }

	  public boolean exists( String key)
	  {
	    return ((Boolean)this.redisTemplate.execute(new RedisCallback<Boolean>() {
	      @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.exists(key.getBytes());
	      }
	    })).booleanValue();
	  }

	  public void set( byte[] key,  byte[] value,  long liveTime)
	  {
	    this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        connection.set(key, value);
	        if (liveTime > 0L) {
	          connection.expire(key, liveTime);
	        }
	        return Long.valueOf(1L);
	      }
	    });
	  }

	  public void set(String key, String value, long liveTime)
	  {
	    set(key.getBytes(), value.getBytes(), liveTime);
	  }

	  public void set(String key, String value)
	  {
	    set(key, value, 0L);
	  }

	  public void set(byte[] key, byte[] value)
	  {
	    set(key, value, 0L);
	  }

	  public String get( String key)
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback<String>() {
	      @Override public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.get(key.getBytes()));
	      }
	    });
	  }

	  public Set<byte[]> getKeys( String pattern)
	  {
		  
	    return (Set<byte[]>) this.redisTemplate.execute(new RedisCallback< Set<byte[]>>() {
	      @Override public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.keys(pattern.getBytes());
	      }
	    });
	  }

	  public Long incr( String key)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.incr(key.getBytes());
	      }
	    });
	  }

	  public Long incrBy( String key,  long number)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.incrBy(key.getBytes(), number);
	      }
	    });
	  }

	  public Double incrBy( String key,  double number)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Double>() {
	      @Override public Double doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.incrBy(key.getBytes(), number);
	      }
	    });
	  }

	  public Long decr( String key)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.decr(key.getBytes());
	      }
	    });
	  }

	  public Long decrBy( String key,  long number)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.decrBy(key.getBytes(), number);
	      }
	    });
	  }

	  public Long lpush(String key, String value)
	  {
	    return lpush(key, value, 0L);
	  }

	  public Long lpush( String key,  String value,  long liveTime)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        Long r = connection.lPush(key.getBytes(), new byte[][] { value.getBytes() });
			  if (liveTime > 0L) {
				  connection.expire(key.getBytes(), liveTime);
			  }
	        return r;
	      }
	    });
	  }

	  public Long rpush(String key, String value)
	  {
	    return rpush(key, value, 0L);
	  }

	  public Long rpush( String key,  String value,  long liveTime)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        Long r = connection.rPush(key.getBytes(), new byte[][] { value.getBytes() });
			  if (liveTime > 0L) {
				  connection.expire(key.getBytes(), liveTime);
			  }
	        return r;
	      }
	    });
	  }

	  public String lpop( String key)
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback<String>() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.lPop(key.getBytes()));
	      }
	    });
	  }

	  public String rpop( String key)
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback<String>() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.rPop(key.getBytes()));
	      }
	    });
	  }

	  public List<String> lrangeAll(String key)
	  {
	    return byteListToStrList(lrangeAllByte(key));
	  }

	  public List<byte[]> lrangeAllByte( String key)
	  {
	    return this.redisTemplate.execute(new RedisCallback<List<byte[]>>() {
	      @Override
		  public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.lRange(key.getBytes(), 0L, -1L);
	      }
	    });
	  }

	  public List<String> lrange(String key, long start, long end)
	  {
	    return byteListToStrList(lrangeByte(key, start, end));
	  }

	  public List<byte[]> lrangeByte( String key,  long start, long end)
	  {
	    return this.redisTemplate.execute(new RedisCallback<List<byte[]>>() {
	      @Override
		  public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.lRange(key.getBytes(), start, end);
	      }
	    });
	  }

	  public Long llen( String key)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.lLen(key.getBytes());
	      }
	    });
	  }

	  public Long rpop( String key,  long count, String value)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.lRem(key.getBytes(), count, key.getBytes());
	      }
	    });
	  }

	public Long linsert(String key, RedisListCommands.Position where, String pivot, String value)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.lInsert(key.getBytes(), where, pivot.getBytes(), value.getBytes());
	      }
	    });
	  }

	  public Long sadd(String key, byte[]... values)
	  {
	    return sadd(key, 0L, values);
	  }

	  public Long sadd(String key, List<String> values)
	  {
		  if ((values == null) || (values.size() == 0)) {
			  return Long.valueOf(0L);
		  }
	    return sadd(key, 0L, (byte[][])strListToByteList(values).toArray());
	  }

	  public Long sadd(String key, long liveTime, String value)
	  {
	    return sadd(key, liveTime, new byte[][] { value.getBytes() });
	  }

	  public Long sadd(String key, String value)
	  {
	    return sadd(key, 0L, new byte[][] { value.getBytes() });
	  }

	public Long sadd(String key,long liveTime,byte[]... values)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        connection.sAdd(key.getBytes(), values);
			  if (liveTime > 0L) {

				  connection.expire(key.getBytes(), liveTime);
			  }
	        return Long.valueOf(values.length);
	      }
	    });
	  }

	  public Long sRem( String key,  byte[]... values)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.sRem(key.getBytes(), values);
	      }
	    });
	  }

	  public String spop( String key)
	  {
	    return this.redisTemplate.execute(new RedisCallback<String>() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.sPop(key.getBytes()));
	      }
	    });
	  }

	  public String sRandMember( String key)
	  {
	    return this.redisTemplate.execute(new RedisCallback<String>() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.sRandMember(key.getBytes()));
	      }
	    });
	  }

	  public Boolean sIsMember( String key,  String value)
	  {
	    return (Boolean)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.sIsMember(key.getBytes(), value.getBytes());
	      }
	    });
	  }

	  public List<String> sMembers( String key)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.sMembers(key.getBytes());
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public Long scard( String key)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.sCard(key.getBytes());
	      }
	    });
	  }

	  public Boolean zadd(String key, double score, String value)
	  {
	    return zadd(key, score, value, 0L);
	  }
	
	  public Boolean zadd( String key,  double score, String value,  long liveTime)
	  {
	    return (Boolean)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        try {
	          connection.zAdd(key.getBytes(), score, value.getBytes("utf-8"));
	        }
	        catch (UnsupportedEncodingException e) {
	          e.printStackTrace();
	        }
			  if (liveTime > 0L) {

				  connection.expire(key.getBytes(), liveTime);
			  }
	        return true;
	      }
	    });
	  }

	  public Long zRem( String key,  byte[]... values)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRem(key.getBytes(), values);
	      }
	    });
	  }

	  public Long zRemRangeByScore( String key,  double min, double max)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRemRangeByScore(key.getBytes(), min, max);
	      }
	    });
	  }

	  public Long zRemRangeByRank( String key,  long begin, long end)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRemRange(key.getBytes(), begin, end);
	      }
	    });
	  }

	  public List<String> zRevRangeByScore( String key,  double begin, double end)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRevRangeByScore(key.getBytes(), begin, begin);
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public List<String> zRangeByScore( String key,  double begin, double end)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRevRangeByScore(key.getBytes(), begin, begin);
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public String zRangeByScore(String key, double store)
	  {
	    List list = zRangeByScore(key, store, store);
	    if (list!=null && list.size()>0) {
	      return (String)list.get(0);
	    }
	    return null;
	  }

	  public Long zRank( String key,  String value)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRank(key.getBytes(), value.getBytes());
	      }
	    });
	  }

	  public Long zRevRank( String key,  String value)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRevRank(key.getBytes(), value.getBytes());
	      }
	    });
	  }

	  public List<String> zRange( String key,  long begin, long end)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRange(key.getBytes(), begin, end);
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public List<String> zRevRange( String key,  long begin, long end)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zRevRange(key.getBytes(), begin, end);
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public Long zCard( String key)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback<Object>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zCard(key.getBytes());
	      }
	    });
	  }

	  public Long zCount( String key,  double min, double max)
	  {
	    return this.redisTemplate.execute(new RedisCallback<Long>() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.zCount(key.getBytes(), min, max);
	      }
	    });
	  }

	  public Boolean hSet(String key, String field, String value)
	  {
	    return hSet(key, field, value, 0L);
	  }

	  public Boolean hSet( String key,  String field,  String value,  long liveTime)
	  {
	    return (Boolean)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        connection.hSet(key.getBytes(), field.getBytes(), RedisUtils.this.stringToByte(value));
			  if (liveTime > 0L) {

				  connection.expire(key.getBytes(), liveTime);
			  }
	        return Boolean.valueOf(true);
	      }
	    });
	  }

	  public void hSet(String key, Map<String, String> hashes)
	  {
	    hSet(key, hashes, 0L);
	  }

	  public void hSet( String key,  Map<String, String> hashes,  long liveTime)
	  {
	    this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Object doInRedis(RedisConnection connection) throws DataAccessException {
	        Iterator it = hashes.entrySet().iterator();
	        while (it.hasNext()) {
	          Map.Entry et = (Map.Entry)it.next();
	          RedisUtils.this.hSet(key, (String)et.getKey(), (String)et.getValue());
	        }
			  if (liveTime > 0L) {
				  connection.expire(key.getBytes(), liveTime);
			  }
	        return null;
	      }
	    });
	  }

	  public void hSetByteMap( String key,  Map<byte[], byte[]> hashes)
	  {
	    this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Object doInRedis(RedisConnection connection) throws DataAccessException {
	        connection.hMSet(key.getBytes(), hashes);
	        return null;
	      }
	    });
	  }

	  public String hGet( String key,  String field)
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return RedisUtils.this.byteToString(connection.hGet(key.getBytes(), field.getBytes()));
	      }
	    });
	  }

	  public List<String> hGet(String key, byte... fields)
	  {
	    return byteListToStrList(hGetsByte(key, fields));
	  }

	  public List hGetsByte(String key, byte... fields)
	  {
	    return (List)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hMGet(key.getBytes(), new byte[][] { fields });
	      }
	    });
	  }

	  public Map<String, String> hGetAll( String key)
	  {
	    Map values = (Map)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Map<byte[], byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hGetAll(key.getBytes());
	      }
	    });
	    return byteMapToStrMap(values);
	  }

	  public Long hDel( String key,  String field)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hDel(key.getBytes(), new byte[][] { field.getBytes() });
	      }
	    });
	  }

	  public Long hLen( String key)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hLen(key.getBytes());
	      }
	    });
	  }

	  public Boolean hExists( String key,  String field)
	  {
	    return (Boolean)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hExists(key.getBytes(), field.getBytes());
	      }
	    });
	  }

	  public List<String> hKeys( String key)
	  {
	    Set values = (Set)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Set<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hKeys(key.getBytes());
	      }
	    });
	    return byteSetToStrSet(values);
	  }

	  public List<String> hVals( String key)
	  {
	    List values = (List)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hVals(key.getBytes());
	      }
	    });
	    return byteListToStrList(values);
	  }

	  public Long hIncrBy( String key,  String field,  long delta)
	  {
	    return (Long)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hIncrBy(key.getBytes(), field.getBytes(), delta);
	      }
	    });
	  }

	  public Double hIncrBy( String key,  String field,  double delta)
	  {
	    return (Double)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Double doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.hIncrBy(key.getBytes(), field.getBytes(), delta);
	      }
	    });
	  }

	  public String flushDB()
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        connection.flushDb();
	        return "ok";
	      }
	    });
	  }

	  public long dbSize()
	  {
	    return ((Long)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public Long doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.dbSize();
	      }
	    })).longValue();
	  }

	  public String ping()
	  {
	    return (String)this.redisTemplate.execute(new RedisCallback() {
	      @Override
		  public String doInRedis(RedisConnection connection) throws DataAccessException {
	        return connection.ping();
	      }
	    });
	  }

	  protected String byteToString(byte[] bytes)
	  {
		  if (bytes == null) {

			  return null;
		  }
		  if (bytes.length == 0) {

			  return "";
		  }
	    try {
	      return new String(bytes, "utf-8");
	    } catch (UnsupportedEncodingException e) {
	      e.printStackTrace();
	      throw new RuntimeException(e);
	    }
	  }

	  protected byte[] stringToByte(String value)
	  {
		  if (value == null) {
			  return null;
		  }
	    try {
	      return value.getBytes("utf-8");
	    } catch (UnsupportedEncodingException e) {
	      e.printStackTrace();
	      throw new RuntimeException(e);
	    }
	  }

	  protected List<String> byteListToStrList(List<byte[]> values)
	  {
		  if (values == null) {
			  return null;
		  }
	    List<String> results = new LinkedList<String>();
		  for (byte[] value : values) {
			  results.add(byteToString(value));
		  }
	    return results;
	  }

	  protected List<byte[]> strListToByteList(List<String> values)
	  {
		  if (values == null) {

			  return null;
		  }
	    List results = new LinkedList();
		  for (String value : values) {
			  results.add(stringToByte(value));
		  }
	    return results;
	  }

	  protected List<String> byteSetToStrSet(Set<byte[]> values)
	  {
	    if (values == null) {
	      return null;
	    }
	    List results = new LinkedList();
		  for (byte[] value : values) {
			  results.add(byteToString(value));
		  }
	    return results;
	  }

	  protected Map<String, String> byteMapToStrMap(Map<byte[], byte[]> values)
	  {
	    if (values == null)
	      return null;
	    Map results = new HashMap();
	    Iterator it = values.entrySet().iterator();
	    while (it.hasNext()) {
	      Map.Entry et = (Map.Entry)it.next();
	      results.put(byteToString((byte[])et.getKey()), byteToString((byte[])et.getValue()));
	    }
	    return results;
	  }

	  public Long getMaxId(String key) {
	    if (exists(key)) {
	      incr(key);
	      return Long.valueOf(Long.parseLong(get(key)));
	    }

	    set(key, "1");
	    return Long.valueOf(1L);
	  }

	    public Boolean setNX( String key,  String value,  long liveTime) {
	        return (Boolean)this.redisTemplate.execute(new RedisCallback<Boolean>() {
	            @Override
				public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
	                Boolean flag = null;
	                try {
	                    flag = connection.setNX(key.getBytes(), value.getBytes("UTF-8"));
	                } catch (UnsupportedEncodingException e) {
	                    e.printStackTrace();
	                }
	                connection.expire(key.getBytes(), liveTime);
	                return flag;
	            }
	        });
	    }
		public String getSet( String key,  String value) {
	        Object obj = null;
	        try {
	            obj = redisTemplate.execute(new RedisCallback<Object>() {
	                @Override
	                public Object doInRedis(RedisConnection connection) throws DataAccessException {
	                    StringRedisSerializer serializer = new StringRedisSerializer();
	                    byte[] ret = connection.getSet(serializer.serialize(key), serializer.serialize(value));
	                    connection.close();
	                    return serializer.deserialize(ret);
	                }
	            });
	        } catch (Exception e) {
	        	log.error("redis getSet error,key:"+key);
	        }
	        return obj != null ? (String) obj : null;
		}
	
}
